package com.tarena.csmall.seckill.security.filter;

import cn.tedu.mall.common.exception.CoolSharkServiceException;
import cn.tedu.mall.common.pojo.domain.CsmallAuthenticationInfo;
import cn.tedu.mall.common.restful.ResponseCode;
import cn.tedu.mall.common.utils.JwtTokenUtils;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

/**
 * 来完成解析 jwt 生成认证对象的逻辑
 * 最终这个对象交给 security使用
 * 过滤器必须实现过滤器的接口 才能生效
 */
@Slf4j
public class MyAuthenticationFilter extends OncePerRequestFilter{
    //生成需要用到2个必要参数,测试时,是set进去的,但是容器启动需要给属性,
    //secret和expiration要和sso一致
    @Autowired
    private JwtTokenUtils jwtTokenUtils;
    //底层要求实现doFilter
    @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
        FilterChain filterChain) throws ServletException, IOException {
        //获取请求头 Authorization
        String authorization = request.getHeader("Authorization");
        String jwt=null;//一旦下面的两个if都判断true jwt才可能不是null
        if (StringUtils.isNotEmpty(authorization)){
            //继续判断是否存在合法JWT
            if (authorization.startsWith("Bearer ")){
                //jwt才是合法携带的
                jwt=authorization.substring(7);
            }
        }
        if (jwt!=null){
            //继续解析
            try{
                CsmallAuthenticationInfo info = jwtTokenUtils.getUserInfo(jwt);
                if (info==null){
                    throw new CoolSharkServiceException(ResponseCode.BAD_REQUEST,"jwt无法解析");
                }
                //征程封装认证对象
                UsernamePasswordAuthenticationToken
                    authentication=new UsernamePasswordAuthenticationToken(info,null,null);
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }catch (Exception e){
                log.error("解析jwt失败",e);
            }
        }
        filterChain.doFilter(request,response);
    }
}
